home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / sipp / libsipp / wood.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-03  |  4.4 KB  |  151 lines

  1. /**
  2.  ** sipp - SImple Polygon Processor
  3.  **
  4.  **  A general 3d graphic package
  5.  **
  6.  **  Copyright Equivalent Software HB  1992
  7.  **
  8.  ** This program is free software; you can redistribute it and/or modify
  9.  ** it under the terms of the GNU General Public License as published by
  10.  ** the Free Software Foundation; either version 1, or any later version.
  11.  ** This program is distributed in the hope that it will be useful,
  12.  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  ** GNU General Public License for more details.
  15.  ** You can receive a copy of the GNU General Public License from the
  16.  ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  **/
  18.  
  19. /**
  20.  ** wood.c - Wood shader: Simulates wood using multiple skewed "cylinders"
  21.  **          distorted with noise and turbulence.
  22.  **/
  23.  
  24. #include <math.h>
  25. #include <stdio.h>
  26.  
  27. #include <sipp.h>
  28. #include <noise.h>
  29. #include <shaders.h>
  30.  
  31.  
  32. #define BOARDSIZE  45.0    /* "Log" or "board" size in texture coordinates */
  33.  
  34.  
  35. void
  36. wood_shader(pos, normal, texture, view_vec, lights, wd, color, opacity)
  37.     Vector      *pos;
  38.     Vector      *normal;
  39.     Vector      *texture;
  40.     Vector      *view_vec;
  41.     Lightsource *lights;
  42.     Wood_desc   *wd;
  43.     Color       *color;
  44.     Color       *opacity;
  45. {
  46.     Vector    tpos;
  47.     Vector    tmp;
  48.     Surf_desc surface;
  49.     double chaos;
  50.     double val;
  51.     double val2;
  52.     double skewoff;
  53.     double t;
  54.     double rad;
  55.  
  56.     if (!noise_ready) {
  57.         noise_init();
  58.     }
  59.  
  60.     /*
  61.      * Scale the texture coordinates.
  62.      */
  63.     VecScalMul(tpos, wd->scale, *texture);
  64.  
  65.     /*
  66.      * Get some noise values. Drag out the texture in
  67.      * the direction of the "stem" of the fictive tree, the
  68.      * pattern should vary less along that direction.
  69.      */
  70.     tpos.x *= 0.08;
  71.     chaos = turbulence(&tpos, 5) * 0.5;
  72.     val2 = noise(&tpos);
  73.  
  74.     /*
  75.      * Make the pattern "semi"-periodic so it looks as if
  76.      * a new board is used at regular intervals
  77.      */
  78.     if (tpos.z > 0.0) {
  79.         tmp.z = floor((tpos.z + BOARDSIZE * 0.5) / BOARDSIZE);
  80.         tpos.z -= tmp.z * BOARDSIZE;
  81.     } else {
  82.         tmp.z = floor((BOARDSIZE * 0.5 - tpos.z) / BOARDSIZE);
  83.         tpos.z += tmp.z * BOARDSIZE;
  84.     }
  85.     if (tpos.y > 0.0) {
  86.         tmp.y = floor((tpos.y + BOARDSIZE * 0.5) / BOARDSIZE);
  87.         tpos.y -= tmp.y * BOARDSIZE;
  88.     } else {
  89.         tmp.y = floor((BOARDSIZE * 0.5 - tpos.y) / BOARDSIZE);
  90.         tpos.y += tmp.y * BOARDSIZE;
  91.     }
  92.  
  93.     /* 
  94.      * Skew the "stem" a bit so the "cylinders" isn't perfectly
  95.      * symmertic about the x-axis. Skew the different "logs"
  96.      * slightly differently.
  97.      */
  98.     tmp.x = 0.0;
  99.     skewoff = noise(&tmp);
  100.     tpos.z -= (0.05 + 0.03 * skewoff) * (texture->x * wd->scale - 2.0);
  101.     tpos.y -= (0.05 + 0.03 * skewoff) * (texture->x * wd->scale - 2.0);
  102.  
  103.     /*
  104.      * Calculate the distance from the middle of the "stem" and
  105.      * distort this distance with the turbulence value.
  106.      */
  107.     rad = sqrt(tpos.y * tpos.y + tpos.z * tpos.z);
  108.     rad += chaos;
  109.     val = rad - floor(rad);
  110.  
  111.     /*
  112.      * Choose a color dependent on the distorted distance.
  113.      */
  114.     if (val < 0.1) {
  115.         surface.color.red = wd->base.red;
  116.         surface.color.grn = wd->base.grn;
  117.         surface.color.blu = wd->base.blu;
  118.     } else if (val < 0.9) {
  119.         t = 1.0 - pow(val / 0.8 - 0.1, 6.0);
  120.         surface.color.red = wd->ring.red + t * (wd->base.red 
  121.                                                   - wd->ring.red);
  122.         surface.color.grn = wd->ring.grn + t * (wd->base.grn 
  123.                                                   - wd->ring.grn);
  124.         surface.color.blu = wd->ring.blu + t * (wd->base.blu 
  125.                                                   - wd->ring.blu);
  126.     } else {
  127.         surface.color.red = wd->ring.red;
  128.         surface.color.grn = wd->ring.grn;
  129.         surface.color.blu = wd->ring.blu;
  130.     }
  131.  
  132.     /*
  133.      * Add a little extra "noise" so the pattern doesn't get
  134.      * too regular, this could be small cracks, or other anomalies
  135.      * in the wood.
  136.      */
  137.     if (val2 < 0.01 && val2 > 0.0) {
  138.         surface.color.red = wd->ring.red;
  139.         surface.color.grn = wd->ring.grn;
  140.         surface.color.blu = wd->ring.blu;
  141.     }
  142.  
  143.  
  144.     surface.ambient  = wd->ambient;
  145.     surface.specular = wd->specular;
  146.     surface.c3       = wd->c3;
  147.     surface.opacity  = wd->opacity;
  148.     basic_shader(pos, normal, texture, view_vec, lights, &surface, 
  149.                  color, opacity);
  150. }
  151.